// 用于线上运行的web服务程序

const Koa = require('koa')
const server = new Koa()
const { createBundleRenderer } = require('vue-server-renderer')
const fs = require('fs')
const path = require('path')
const MFS = require('memory-fs')
const chokidar = require('chokidar')
const webpack = require('webpack')
const clientConfig = require('./webpack.client.config')
const clientCompiler = webpack(clientConfig)
const serverConfig = require('./webpack.server.config')
const serverCompiler = webpack(serverConfig)
const isProd = process.env.NODE_ENV === 'production'


// 在开发环境中，每当监听到相关文件发生变化时，应当重新生成一个renderer，
// 该方法专门用于生成新的renderer，当然，在生产环境中，改方法只需用一次
const createRenderer = (bundle, clientManifest, template) => createBundleRenderer(bundle, {
  template,
  clientManifest,
  // for component caching
  cache: LRU({
    max: 1000,
    maxAge: 1000 * 60 * 15
  }),
  // this is only needed when vue-server-renderer is npm-linked
  basedir: resolve('./dist'),
  // recommended for performance
  runInNewContext: false
})


const render = function () {
  let bundle, clientManifest, template
  let renderer = createRenderer()
  renderer.renderToString

  return context => renderer.renderToString(context)
}();

const renderer = createBundleRenderer(serverBundle, {
  runInNewContext: false, // 推荐
  template: fs.readFileSync('./index.template.html', 'utf-8'), // （可选）页面模板
  clientManifest // （可选）客户端构建 manifest
})

// 在服务器处理函数中……
server.get('*', (req, res) => {
  const context = { url: req.url }
  // 这里无需传入一个应用程序，因为在执行 bundle 时已经自动创建过。
  // 现在我们的服务器与应用程序已经解耦！
  renderer.renderToString(context, (err, html) => {
    // 处理异常……
    res.end(html)
  })
})

server.use(async ctx => {
  const context = {
    title: '娱乐猫',
    url: ctx.url
  }
  // 这里无需传入一个应用程序，因为在执行 bundle 时已经自动创建过。
  // 现在我们的服务器与应用程序已经解耦！
  renderer.renderToString(context).then(html => ctx.body = html).catch(err => console.error(err))
})

server.listen(8080, () => console.log('Server listening on: http://localhost:8080'))